	// verilator_coverage annotation
	`include "./AdamRiscv/define.vh"
	
	module stage_ex(
 019817	    input  wire[31:0]  ex_pc,  //pc_now
 000707	    input  wire[31:0]  ex_regs_data1,
 000629	    input  wire[31:0]  ex_regs_data2,
 000392	    input  wire[31:0]  ex_imm,
 000041	    input  wire[2:0]   ex_func3_code, 
%000007	    input  wire        ex_func7_code,
 019767	    input  wire[2:0]   ex_alu_op,
 000036	    input  wire[1:0]   ex_alu_src1,
 000034	    input  wire[1:0]   ex_alu_src2,
 006579	    input  wire        ex_br_addr_mode,
 006584	    input  wire        ex_br,
	    //forwarding
 000031	    input  wire[1:0]   forwardA,
 000027	    input  wire[1:0]   forwardB,
 000658	    input  wire[31:0]  me_alu_o,
 000486	    input  wire[31:0]  w_regs_data,
	
 000639	    output wire[31:0]  ex_alu_o,
 020105	    output wire[31:0]  br_pc, //branch address
 006569	    output wire        br_ctrl,
	
 000291	    input wire[31:0] ex_m_data,
 506047	    input wire[31:0] ex_r_matrix_mopa[3:0],
%000284	    output wire[31:0] matrix_mopa_o[3:0]
	);
	
 026326	wire [3:0]  alu_ctrl;
 000387	wire [31:0] op_A;
 000571	wire [31:0] op_A_pre;
 000649	wire [31:0] op_B;
 000669	wire [31:0] op_B_pre;
%000007	wire        br_mark;
 019864	wire [31:0] br_addr_op_A; 
	
	alu_control u_alu_control(
	    .alu_op     (ex_alu_op     ),
	    .func3_code (ex_func3_code ),
	    .func7_code (ex_func7_code ),
	    .alu_ctrl_r (alu_ctrl      )
	);
	
	
	alu u_alu(
	    .alu_ctrl (alu_ctrl      ),
	    .op_A     (op_A          ),
	    .op_B     (op_B          ),
	    .alu_o    (ex_alu_o      ),
	    .br_mark  (br_mark       ),
	    .ex_r_matrix_mopa(ex_r_matrix_mopa),
	    .matrix_mopa_o(matrix_mopa_o)
	);
	
	assign br_addr_op_A = (ex_br_addr_mode == `J_REG) ? ex_regs_data1 : ex_pc;
	assign br_pc = br_addr_op_A + ex_imm;
	assign op_B = (ex_alu_src2 == `PC_PLUS4)? 32'd4 : (ex_alu_src2 == `IMM)? ex_imm : (ex_alu_src2 == `ZERO)? 32'h0:op_B_pre;
	assign op_A = (ex_alu_src1 == `NULL)? 32'd0 : (ex_alu_src1 == `PC)? ex_pc : (ex_alu_src1 == `MOVE && forwardA != `MEM_WB_M_A)? ex_m_data : op_A_pre;
	assign op_B_pre = (forwardB == `EX_MEM_B)? me_alu_o : (forwardB == `MEM_WB_B)? w_regs_data : (forwardB == `MEM_WB_M_B)? me_alu_o : ex_regs_data2;
	assign op_A_pre = (forwardA == `EX_MEM_A)? me_alu_o : (forwardA == `MEM_WB_A)? w_regs_data : (forwardA == `MEM_WB_M_A)? me_alu_o : ex_regs_data1;
	assign br_ctrl = br_mark && ex_br;
	
	always @(*) begin
 000016	    if (|forwardA)
	        $display("forwardA! OP_A: %h",op_A);
%000008	    else if (|forwardB)
	        $display("forwardB! OP_B: %h",op_B);
	end
	
	endmodule
	
